package com.MasterDevelopers.MessageMaster;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.telephony.gsm.SmsManager;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.AdapterView.AdapterContextMenuInfo;

public class MessageMaster extends ListActivity {
	private static final int ACTIVITY_CREATE = 0;
	private static final int ACTIVITY_EDIT = 1;

	private static final int DIALOG_SENDING_MESSAGE = 0;
	private static final int DIALOG_ERROR = 1;
	private static final int DIALOG_MESSAGE_SENT = 2;

	private static final int INSERT_ID = Menu.FIRST;
	private static final int EDIT_ID = Menu.FIRST + 1;
	private static final int DELETE_ID = Menu.FIRST + 2;
	private static final int IMPORT_ID = Menu.FIRST + 3;
	private static final int EXPORT_ID = Menu.FIRST + 4;

	private static final String TAG = "MessageMaster";

	private DbAdapter mDbHelper;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.text_list);

		mDbHelper = new DbAdapter(this);
		mDbHelper.open();
		fillData();
		registerForContextMenu(getListView());
	}

	private void fillData() {
		// Get all of the rows from the database and create the item list
		Cursor notesCursor = mDbHelper.fetchCursorForAllTextMessages();
		startManagingCursor(notesCursor);

		// Create an array to specify the fields we want to display in the list
		// (only TITLE)
		String[] from = new String[] { DbAdapter.KEY_TITLE };

		// and an array of the fields we want to bind those fields to (in this
		// case just text1)
		int[] to = new int[] { R.id.text1 };

		// Now create a simple cursor adapter and set it to display
		SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
				R.layout.text_row, notesCursor, from, to);
		setListAdapter(notes);
	}

	/*** Options Menu (menu button) Creation ***/
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, INSERT_ID, 0, R.string.menu_insert);
		menu.add(0, EXPORT_ID, 0, R.string.menu_export);
		menu.add(0, IMPORT_ID, 0, R.string.menu_import);
		return true;
	}

	/*** Options Menu (menu button) Click Handling ***/
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch (item.getItemId()) {
		case INSERT_ID:
			createMessage();
			break;
		case EXPORT_ID:
			exportMessages();
			break;
		case IMPORT_ID:
			importMessages();
		}
		return super.onMenuItemSelected(featureId, item);
	}

	/*** Dialog Message Creation ***/
	@Override
	protected Dialog onCreateDialog(int id) {
		Dialog dialog;

		switch (id) {
		case DIALOG_SENDING_MESSAGE:
			dialog = ProgressDialog.show(this, "", "Loading. Please wait...",
					true);
			break;
		case DIALOG_ERROR:
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage("There was an error").setCancelable(false)
					.setNegativeButton("OK",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									dialog.cancel();
								}
							});
			dialog = builder.create();
			break;
		case DIALOG_MESSAGE_SENT:
			AlertDialog.Builder builder2 = new AlertDialog.Builder(this);
			builder2.setMessage("Your message was sent").setCancelable(false);
			builder2.setPositiveButton("OK",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							dialog.cancel();
						}
					});
			builder2.setNegativeButton("Close",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							MessageMaster.this.finish();
						}
					});
			dialog = builder2.create();
			break;
		default:
			dialog = null;
		}
		return dialog;

	}

	/*** Context Menu (long click) Creation ***/
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		menu.add(0, EDIT_ID, 0, R.string.menu_edit);
		menu.add(0, DELETE_ID, 0, R.string.menu_delete);
	}

	/*** Context Menu (long click) Handling ***/
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info;
		switch (item.getItemId()) {
		case EDIT_ID:
			info = (AdapterContextMenuInfo) item.getMenuInfo();
			editItem(info.id);
			return true;
		case DELETE_ID:
			info = (AdapterContextMenuInfo) item.getMenuInfo();
			mDbHelper.deleteTextMessage(info.id);
			fillData();
			return true;
		}
		return super.onContextItemSelected(item);
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		try {
			// showDialog(DIALOG_SENDING_MESSAGE);
			sendMessage(id);
			// dismissDialog(DIALOG_SENDING_MESSAGE);
		} catch (Exception ex) {
			Log.i(TAG, ex.getMessage());
			showDialog(DIALOG_ERROR);
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode,
			Intent intent) {
		super.onActivityResult(requestCode, resultCode, intent);
		fillData();
	}

	private void editItem(Long id) {
		Intent i = new Intent(this, TextEdit.class);
		i.putExtra(DbAdapter.KEY_ROWID, id);
		startActivityForResult(i, ACTIVITY_EDIT);
	}

	private void createMessage() {
		Intent i = new Intent(this, TextEdit.class);
		startActivityForResult(i, ACTIVITY_CREATE);
	}

	private void sendMessage(long id) {
		try {
			Message m = mDbHelper.fetchTextMessage(id);
			sms(m.getAddresses(), m.getBody());
			showDialog(DIALOG_MESSAGE_SENT);
		} catch (Exception ex) {
			Log.i(TAG, ex.getMessage());
			showDialog(DIALOG_ERROR);
		}
	}

	public void sms(Address to, String text) {
		Log.i(TAG, "Sending '" + text + "' to: " + to);
		SmsManager.getDefault().sendTextMessage(to.getAddress(), null, text, null, null);
	}

	@Override
	protected void onPause() {
		super.onPause();
		Log.i(TAG, "On Pause");
	}

	@Override
	protected void onResume() {
		super.onResume();
		Log.i(TAG, "On Pause");
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		Log.i(TAG, "On Save Instance State");
	};

	// Import/Export
	private void exportMessages() {
		String fname = getResources().getString(R.string.file_import);
		writeToFile(fname, "Josh wrote to a file");
	}

	private void importMessages() {
		String fname = getResources().getString(R.string.file_import);
		String data = readFromFile(fname);
		
		// hack to kill the warnings for a method that's not done yet
		if (data == null) return;
		return;
	}

	private void writeToFile(String fname, String data) {
		FileOutputStream out = null;
		try {
			Log.d(TAG, "Writing to " + fname + "...");
			out = openFileOutput(fname, MODE_PRIVATE);
			out.write(data.getBytes());
			out.close();
			Log.d(TAG, "Write Succesful");
		} catch (Exception ex) {
			Log.e(TAG, "Error exporting messages:  " + ex.getMessage());
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					// If we can't close the stream, then just get on with our
					// lives.
					e.printStackTrace();
				}
			}
		}
	}
	
	private String readFromFile(String fname) {
		FileInputStream in = null;
		String data = null;
		try {
			Log.d(TAG, "Reading...");
			in = openFileInput(fname);

			FileReader fr = new FileReader(in.getFD());
			BufferedReader br = new BufferedReader(fr);
			 data = br.readLine();
			in.close();

			Log.d(TAG, "Read:  " + data);
		} catch (Exception ex) {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					// If we can't close the stream, then just get on with our
					// lives.
					e.printStackTrace();
				}
			}
		}
		return data;
	}
}